package it.aqquadro.arex;

import java.io.IOException;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ArexDispatcher extends HttpServlet {
	private static final Logger log = Logger.getLogger(ArexDispatcher.class.getName());
	private String pathInfo;

	private ArexMouth getAction(HttpServletRequest req, HttpServletResponse resp) throws IOException {

		Object instance = req.getAttribute(ArexFilter.REXY_ATTRIBUTE);

		this.pathInfo = req.getPathInfo();

		if (instance != null) {
			log.info("instance class: " + instance.getClass().getName());

			if (instance instanceof ArexMouth) {

				ArexMouth arex = (ArexMouth) instance;

				arex.setReq(req);
				arex.setResp(resp);
				arex.setServletContext(getServletContext());
				return arex;

			} else {
				throw new IOException("Attributo " + ArexFilter.REXY_ATTRIBUTE + " non settato correttamente");
			}
		} else {
			throw new IOException("Attributo " + ArexFilter.REXY_ATTRIBUTE + " non settato correttamente");
		}
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		ArexMouth action = getAction(req, resp);

		if (pathInfo.endsWith(ArexFilter.SEARCH)) {
			// chiamare search
			action.search(req.getParameter("q"));
		} else if (getResourceId(req) != null) {
			action.get(getResourceId(req));
		} else {
			action.get();
		}
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		ArexMouth action = getAction(req, resp);

		if (getResourceId(req) != null) {
			action.post(getResourceId(req));
		} else {
			action.post();
		}
	}

	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		ArexMouth action = getAction(req, resp);
		if (getResourceId(req) != null) {
			action.post(getResourceId(req));
		} else {
			action.post();
		}
	}

	@Override
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		ArexMouth action = getAction(req, resp);
		action.delete();
	}

	@Override
	protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		ArexMouth action = getAction(req, resp);
		action.head();
	}

	@Override
	protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		ArexMouth action = getAction(req, resp);
		if (getResourceId(req) != null) {
			action.post(getResourceId(req));
		} else {
			action.post();
		}
	}

	@Override
	protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		ArexMouth action = getAction(req, resp);
		action.trace();
	}

	/**
	 * Estrae l'id dall'url
	 * 
	 * @param req
	 * @return
	 */
	private String getResourceId(HttpServletRequest req) {
		if (req.getAttribute(ArexFilter.ALIAS_ATTRIBUTE) != null) {
			// controllare che sia stato fornito un id
			String[] splitId = pathInfo.split((String) req.getAttribute(ArexFilter.ALIAS_ATTRIBUTE));
			if (splitId.length > 1) {
				return splitId[splitId.length - 1];
			}
		}

		return null;
	}
}